import { Vector2 } from "./vector";
import { Engine } from "./engine";
import { lerp } from "./utils";

import { CameraManager } from "./camera/camera-manager";
import { ShakeEffect } from "./camera/shake-effect";
import { ZoomEffect } from "./camera/zoom-effect";
import { PathEffect, CameraPathPoint } from "./camera/path-effect";

import { CharacterFocusEffect } from "./camera/character-focus-effect";
import { ActionTriggeredEffect, CinematicAction } from "./camera/action-triggered-effect";
import { CinematicSceneEffect, CinematicKeyframe } from "./camera/cinematic-scene-effect";
import { CharacterZoomEffect } from "./camera/character-zoom-effect";

function log(text:string){
  console.log(text)
}

export class Camera {
  pos = new Vector2();

  private cameraManager: CameraManager;
  private cinematicIndex = 4; // 用于循环不同的运镜效果 
  private zoom = 1; //  

  /**
   * 构造函数，初始化相机实例
   * @param engine - 游戏引擎实例，用于相机控制和场景渲染
   */
  constructor(private engine: Engine) {
    this.cameraManager = new CameraManager(engine);
  }

  update_() {
    const w = this.engine.canvas_.width;
    const h = this.engine.canvas_.height;

    const target = this.engine.player.body_.pos;

    const [maxX, maxY, x, y] = [
      this.engine.level_.size_.x - w,
      this.engine.level_.size_.y - h,
      target.x - w / 2,
      this.moveAtAxis(this.pos.y, target.y - h / 1.7, -5, 50),
    ];
    this.pos.x = Math.min(Math.max(0, x), maxX);
    this.pos.y = Math.min(Math.max(0, y), maxY);
  }

  getZoom(): number {  
    return this.zoom;  
  }  
    
  setZoom(zoom: number): void {  
    this.zoom = zoom;  
  }

  /**
   * 在指定轴上移动当前值到目标值，并限制在[lowerLimit, upperLimit]范围内
   * @param current 当前值
   * @param target 目标值
   * @param lowerLimit 下限
   * @param upperLimit 上限
   * @returns 插值后的新值或原值(当不需要移动时)
   */
  private moveAtAxis(
    current: number,
    target: number,
    lowerLimit: number,
    upperLimit: number,
  ) {
    const d = current - target;
    if (d < lowerLimit || d > upperLimit) {
      return lerp(
        current,
        target + (d < lowerLimit ? lowerLimit : upperLimit),
        0.12,
      );
    }
    return current;
  }

  // 新增的运镜功能接口  
  // 角色聚焦运镜  
  focusOnCharacter(offset: Vector2 = new Vector2(0, -50), zoom: number = 1.2, duration: number = 3000): void {
    if (!this.cameraManager) return;
    const focusEffect = new CharacterFocusEffect(this.engine, offset, zoom);
    focusEffect.start(duration);
    this.cameraManager.addEffect(focusEffect);
  }

  // 在 Camera 类中添加以下方法  
  zoomToCharacter(targetZoom: number = 1.5, duration: number = 2000): void {  
    if (!this.cameraManager) return;  
    const zoomEffect = new CharacterZoomEffect(this.engine, targetZoom);  
    zoomEffect.start(duration);  
    this.cameraManager.addEffect(zoomEffect); 
    // this.zoom =  targetZoom
  } 

  // 动作触发运镜  
  triggerActionCinematic(action: CinematicAction, intensity: number = 1, duration: number = 1000): void {
    if (!this.cameraManager) return;
    const actionEffect = new ActionTriggeredEffect(this.engine, action, intensity);
    actionEffect.start(duration);
    this.cameraManager.addEffect(actionEffect);
  }

  // 电影化场景运镜  
  playCinematicScene(keyframes: CinematicKeyframe[], duration: number): void {
    if (!this.cameraManager) return;
    const sceneEffect = new CinematicSceneEffect(this.engine, keyframes);
    sceneEffect.start(duration);
    this.cameraManager.addEffect(sceneEffect);
  }

  shake(intensity: number = 5, duration: number = 500): void {
    const shakeEffect = new ShakeEffect(this.engine, intensity);
    shakeEffect.start(duration);
    this.cameraManager.addEffect(shakeEffect);
  }

  zoomTo(targetZoom: number, duration: number = 1000): void {
    const zoomEffect = new ZoomEffect(this.engine);
    zoomEffect.setZoom(targetZoom, duration);
    this.cameraManager.addEffect(zoomEffect);
  }

  followPath(path: CameraPathPoint[], duration: number, loop: boolean = false): void {
    const pathEffect = new PathEffect(this.engine, path, loop);
    pathEffect.start(duration);
    this.cameraManager.addEffect(pathEffect);
  }

  clearEffects(): void {
    this.cameraManager.clearEffects();
  }

  // 修改 B 键触发的运镜效果，加入角色元素  
  triggerCinematicEffect(): void {
    if (!this.cameraManager) return;

    this.cameraManager.clearEffects();

    switch (this.cinematicIndex) {
      case 0:
        // 角色特写镜头  
        log("角色特写镜头")
        const {x,y} = this.engine.player.body_.pos;
        this.focusOnCharacter(new Vector2(0, 0), 1.5, 3000);
        break;
      case 1:
        // 跳跃动作运镜  
        log("跳跃动作运镜")
        this.triggerActionCinematic(CinematicAction.JUMP, 1.2, 2000);
        break;
      case 2:
        // 电影化场景  
        log("电影化场景")
        const playerPos = this.engine.player.body_.pos;
        const cinematicKeyframes: CinematicKeyframe[] = [
          { time: 0, cameraPos: new Vector2(playerPos.x - 200, playerPos.y - 100), focusOnPlayer: false, playerOffset: new Vector2(), zoom: 0.8 },
          { time: 0.3, cameraPos: new Vector2(), focusOnPlayer: true, playerOffset: new Vector2(-50, -80), zoom: 1.2 },
          { time: 0.7, cameraPos: new Vector2(), focusOnPlayer: true, playerOffset: new Vector2(50, -40), zoom: 1.5 },
          { time: 1, cameraPos: new Vector2(), focusOnPlayer: true, playerOffset: new Vector2(0, -60), zoom: 1.0 }
        ];
        this.playCinematicScene(cinematicKeyframes, 5000);
        break;
      case 3:
        // 组合效果：震动 + 角色聚焦  
        log("组合效果：震动 + 角色聚焦")
        this.shake(6, 800);
        setTimeout(() => this.focusOnCharacter(new Vector2(0, -40), 1.3, 2000), 400);
        break;
      case 4:  
        // 角色中心放大后缩小  
        this.zoomToCharacter(2.0, 1500);  
        setTimeout(() => this.zoomToCharacter(1.0, 1500), 1500);  
        break;  
    }

    // this.cinematicIndex++;
  }
}
